package com.youbug.mall.ware_wms.service.impl;

import com.youbug.common.constant.WareConstant;
import com.youbug.common.vo.CommonSelectLongValVo;
import com.youbug.common.vo.CommonSelectVo;
import com.youbug.mall.ware_wms.entity.WmsPurchase;
import com.youbug.mall.ware_wms.entity.WmsPurchaseDetail;
import com.youbug.mall.ware_wms.entity.WmsWareInfo;
import com.youbug.mall.ware_wms.mapper.WmsPurchaseMapper;
import com.youbug.mall.ware_wms.service.IWmsPurchaseDetailService;
import com.youbug.mall.ware_wms.service.IWmsPurchaseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youbug.mall.ware_wms.service.IWmsWareInfoService;
import com.youbug.mall.ware_wms.service.IWmsWareSkuService;
import com.youbug.mall.ware_wms.vo.DistributeVo;
import com.youbug.mall.ware_wms.vo.MergeVo;
import com.youbug.mall.ware_wms.vo.PurchaseDoneVo;
import com.youbug.mall.ware_wms.vo.PurchaseItemDoneVo;
import com.youbug.system.entity.User;
import com.youbug.system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import com.youbug.common.vo.QueryVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 采购信息 服务实现类
 * </p>
 *
 * @author youbug
 * @since 2024-05-05
 */
@Service
public class WmsPurchaseServiceImpl extends ServiceImpl<WmsPurchaseMapper, WmsPurchase>
        implements IWmsPurchaseService {

        @Autowired
        private IUserService userService;
        @Autowired
        private IWmsPurchaseService purchaseService;
        @Autowired
        private IWmsPurchaseDetailService purchaseDetailService;
        @Autowired
        private IWmsWareSkuService wareSkuService;
        @Autowired
        private IWmsWareInfoService wareInfoService;

        @Override
        public IPage<WmsPurchase> getWmsPurchasePage(QueryVo<WmsPurchase> queryVo) {

        Page<WmsPurchase> paramPage = new Page<>();

        paramPage.setCurrent(queryVo.getCurrentPage());

        paramPage.setSize(queryVo.getPageSize());

        QueryWrapper<WmsPurchase> wrapper = new QueryWrapper<>();

        WmsPurchase wmsPurchase = queryVo.getPayload();

        if(!ObjectUtils.isEmpty(wmsPurchase)){
            if(StringUtils.hasText(wmsPurchase.getAssigneeName())){
                wrapper.eq("assignee_name", wmsPurchase.getAssigneeName());
            }
            if(wmsPurchase.getAssigneeId()!=null){
                wrapper.eq("assignee_id", wmsPurchase.getAssigneeId());
            }
            if(StringUtils.hasText(wmsPurchase.getPhone())){
                wrapper.eq("phone", wmsPurchase.getPhone());
            }
        }
        if(!ObjectUtils.isEmpty(queryVo.getStartTime())){
            wrapper.gt("create_time", queryVo.getStartTime());
        }
        if(!ObjectUtils.isEmpty(queryVo.getEndTime())){
            wrapper.lt("create_time", queryVo.getEndTime());
        }
        wrapper.orderByDesc("create_time");

        Page<WmsPurchase> page = this.page(paramPage, wrapper);

        List<WmsPurchase> records = page.getRecords();
        if(!CollectionUtils.isEmpty(records)){
            Set<Long> wareIdSet = records.stream().map(WmsPurchase::getWareId).collect(Collectors.toSet());

            List<WmsWareInfo> wareInfos = wareInfoService.listByIds(wareIdSet);

            Map<Long, String> wareMap = wareInfos.stream().collect(Collectors.toMap(WmsWareInfo::getId, e -> e.getAddress() + e.getName()));
            for (WmsPurchase e : records) {
                e.setWareNameTemp(wareMap.get(e.getWareId()));
            }
        }
            return page;
        }

    @Override
    public IPage<WmsPurchase> getUnreceicedWmsPurchasePage(Long wareId) {
        QueryVo<Object> queryVo = new QueryVo<>();
        Page<WmsPurchase> paramPage = new Page<>();

        paramPage.setCurrent(queryVo.getCurrentPage());

        paramPage.setSize(queryVo.getPageSize());

        QueryWrapper<WmsPurchase> wrapper = new QueryWrapper<>();

        wrapper.in("status", 0,1);

        wrapper.eq("ware_id", wareId);

        wrapper.orderByDesc("create_time");

        Page<WmsPurchase> page = this.page(paramPage, wrapper);

        return page;
    }

       /* @Transactional(transactionManager = "transactionManagerXXX", rollbackFor = Exception.class)
        public boolean saveBatch(Collection<WmsPurchase> entityList) {
        return saveBatch(entityList, DEFAULT_BATCH_SIZE);
        }
        */

    @Override
    @Transactional(transactionManager = "transactionManagerWms", rollbackFor = Exception.class)
    public boolean distribute(DistributeVo vo) {
        User user = userService.getById(vo.getUserId());

        WmsPurchase purchase = new WmsPurchase();
        purchase.setAssigneeId(user.getId());
        purchase.setAssigneeName(user.getNickName());
        purchase.setStatus(WareConstant.PurchaseStatusEnum.ASSIGNED.getCode());
        purchase.setPhone(user.getMobile());

        purchaseService.update(purchase,
                new QueryWrapper<WmsPurchase>().eq("id", vo.getPurchaseId()));

        return true;
    }


    @Override
    @Transactional(transactionManager = "transactionManagerWms", rollbackFor = Exception.class)
    public boolean mergePurchase(MergeVo vo) {

        Long purchaseId = vo.getPurchaseId();
        if(purchaseId==null){// 新建
            WmsPurchase purchase = new WmsPurchase();
            purchase.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode());
            this.save(purchase);
            purchaseId = purchase.getId();
        }
        List<Long> items = vo.getItems();
        WmsPurchaseDetail detail = new WmsPurchaseDetail();
        detail.setStatus(WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode());
        detail.setPurchaseId(purchaseId);
        detail.setWareId(vo.getWareId());

        boolean update = purchaseDetailService.update(detail, new QueryWrapper<WmsPurchaseDetail>().in("id", items)
                .eq("status", WareConstant.PurchaseDetailStatusEnum.CREATED.getCode()));

        return update;
    }

    @Override
    public boolean receive(List<Long> ids) {
        WmsPurchase purchase = new WmsPurchase();
        purchase.setStatus(WareConstant.PurchaseStatusEnum.RECEIVE.getCode());
        boolean update = this.update(purchase, new QueryWrapper<WmsPurchase>().in("id", ids));

        WmsPurchaseDetail detail = new WmsPurchaseDetail();
        detail.setStatus(WareConstant.PurchaseDetailStatusEnum.BUYING.getCode());

        boolean update1 = purchaseDetailService.update(detail, new QueryWrapper<WmsPurchaseDetail>().in("purchase_id", ids)
                .eq("status", WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode()));

        return update&&update1;
    }

    @Override
    @Transactional(transactionManager = "transactionManagerWms", rollbackFor = Exception.class)
    public boolean done(PurchaseDoneVo vo) {

        Long purchaseId = vo.getPurchaseId();
        List<PurchaseItemDoneVo> items = vo.getItems();
        Map<Long, PurchaseItemDoneVo> doneVoMap = items.stream().collect(Collectors.toMap(PurchaseItemDoneVo::getItemId, e -> e, (v, v1) -> v));

        boolean flag = true;
        ArrayList<WmsPurchaseDetail> details = new ArrayList<>();

        List<Long> list = items.stream().map(PurchaseItemDoneVo::getItemId).collect(Collectors.toList());

        List<WmsPurchaseDetail> purchaseDetails = purchaseDetailService.listByIds(list);

        for (int i = 0; i < purchaseDetails.size(); i++) {
            WmsPurchaseDetail detail = purchaseDetails.get(i);
            PurchaseItemDoneVo doneVo = doneVoMap.get(detail.getId());
            if(doneVo.getStatus() == WareConstant.PurchaseDetailStatusEnum.FINISH.getCode()){// 正常完成

                detail.setStatus(doneVo.getStatus());
                wareSkuService.addStock(detail.getSkuId(), detail.getWareId(), detail.getSkuNum());
            }else{
                detail.setStatus(WareConstant.PurchaseDetailStatusEnum.HASERROR.getCode());
                detail.setReason(detail.getReason());
                flag = false;
            }
            details.add(detail);
        }
        purchaseDetailService.updateBatchById(details);

        WmsPurchase purchase = new WmsPurchase();
        if(flag){
            purchase.setStatus(WareConstant.PurchaseStatusEnum.FINISH.getCode());
        }else{
            purchase.setStatus(WareConstant.PurchaseStatusEnum.HASERROR.getCode());
        }
        this.update(purchase, new QueryWrapper<WmsPurchase>().eq("id", purchaseId));
        return true;
    }

    @Override
    public boolean checkHasDetail(Long id) {

        int count = purchaseDetailService.count(new QueryWrapper<WmsPurchaseDetail>().eq("purchase_id", id));

        return count > 0;
    }


    @Override
    public List<CommonSelectLongValVo> getAllWareSelect() {

        List<WmsWareInfo> wareInfos = wareInfoService.list();
        if(!CollectionUtils.isEmpty(wareInfos)){
            List<CommonSelectLongValVo> collect = wareInfos.stream().map(e -> {
                return new CommonSelectLongValVo(e.getAddress() + "" + e.getName(), e.getId());
            }).collect(Collectors.toList());
            return collect;
        }
        return Collections.emptyList();
    }
}
